package models;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

public class Creature  implements Serializable
{
	public static final String STAT_MAX_HEALTH = "maxhealth";
	public static final String STAT_SPEED = "speed";
	public static final String STAT_SIGHT = "sight";
	public static final String STAT_STRENGTH = "strength";
	public static final String STAT_ARMOR = "armor";
	public static final String STAT_HEALTH = "health";
	
	private final String name;
	private final Map<String,Float> baseStats;
	private final Collection<Buff> buffs;
	
	public Creature(String name,Map<String,Float> baseStats)
	{
		this.name = name;
		this.baseStats = baseStats;
		this.buffs = new HashSet<Buff>();
	}
	
	/**
	 * Get the name of this creature.
	 * @return
	 */
	public String getName()
	{
		return name;
	}
	
	/**
	 * Sets the health of this creature.
	 * @param health
	 */
	public void setHealth(float health)
	{	
		baseStats.put(STAT_HEALTH, health);
	}
	/**
	 * Returns the base value of the given stat for this creature (Not including any buffs)
	 * @param stat
	 * @return
	 */
	public float getBaseStat(String stat)
	{
		return baseStats.get(stat);
	}
	
	/**
	 * Returns a map of each stat string to its value.
	 * @param stat
	 * @return
	 */
	public Map<String,Float>  getBaseStats()
	{
		return new HashMap<String,Float> (baseStats);
	}
	
	/**
	 * Returns the value of the given stat for this creature, including any buffs
	 * @param stat
	 * @return
	 */
	public float getStat(String stat)
	{
		float value = getBaseStat(stat);
		if(!stat.equals(STAT_HEALTH))
			for(Buff buff: buffs)
				if(buff.getStat().equals(stat))
					value += buff.getValue();
		return value;
	}
	
	/**
	 * Add a new buff to the creature, should only be called by the Game Engine.
	 * @param buff
	 */
	public void addBuff(Buff buff)
	{
		buffs.add(buff);
	}
	
	/**
	 * Remove a buff from the creature, should only be called by the Game Engine.
	 * @param buff
	 */
	public void removeBuff(Buff buff)
	{
		buffs.remove(buff);
	}
	
	/**
	 * Get a list of all the buffs on the creature;
	 * @return
	 */
	public Collection<Buff> getBuffs()
	{
		return Collections.unmodifiableCollection(buffs);
	}
	
	/**
	 * Returns true iff this creature has more then 0 health.
	 * @return
	 */
	public boolean isAlive()
	{
		return getStat(STAT_HEALTH) >0;
	}
}
